﻿/**	rsrc_pond.h
 *	----	Create Time Stamp	--2008-07-22 00:08:41--
 *------------------------------------------------------------------------------
 *	Mean	:
 *	Author	:Nick Shallery	(nicknide@gmail.com)
 *	Version	:0.0.18.35	(2009-10-24 12:30:58)
 *------------------------------------------------------------------------------
**/	/*YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.*/

#if			!defined(__LXUT__RSRC__RSRC_POND__NICK__K_IN_G__)
#define		__LXUT__RSRC__RSRC_POND__NICK__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------
#if			!defined(__LOLIX__LOLI__FILE__K_IN_G__)
	#include	"../../lolix/loli/file.h"
#endif	//	!defined(__LOLIX__LOLI__FILE__K_IN_G__)

#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../../lolix/lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

namespace lxut{namespace rsrc{
	class	rsrc_pond;
	class	rsrc_lacing;

	class	rsrc_fetch;

	namespace __inner{
		union	support_flag;
		union	query_flag;
	}
}}


class	LOLIX_NO_VTABLE	lxut::rsrc::rsrc_pond
	: public lolix::itf
{
public:
	LOLIX_DECLARE_ITF(lxut::rsrc::rsrc_pond, lolix::itf, (0x4c6732fa, 0x730443de, 0x97eaa3ec, 0xad1f0f55));
	LOLIX_DEFINE_FACTORY((0xeee95448, 0xb5cf4a83, 0x85639be8, 0x3a0242f3), (rsrc_pond** out_ptr, lolix::loli::file_volume* fv/*, lolix::loli::file**/, bool write_able));

	typedef	lolix::lx_u64	id_type;
	static const id_type bad_id = 0xffffffffffffffff;

	typedef	__inner::support_flag	support_flag;
	typedef	__inner::query_flag	query_flag;


	struct	user_data
	{
		void*				usr_dat;
		lolix::LOLIX_ITF_ID	itf_id;	//	fetcher
	};


	//===========================================================================
	//	注册一个资源解析插件
	//---------------------------------------------------------------------------
	//	fetch		[i ]	: 等待注册的 fetch
	//	rsrc_id		[i ] =0	: 注册到何种资源类型上.
	//	flag_mask	[io] =0	: i: 申请注册的类型
	//							  o: 注册成功的类型:从低到高分别为 ENUM_CAN_DO
	//								所对应的权限
	//---------------------------------------------------------------------------
	//	注册成功,  rsrc_fetch 内部会自动增加引用计数, 因此外部可以安全释放
	//	flag_mask 如果有效， 则内部会被请零, 且不管返回值如何, 都会被设置
	//		如果指针无效的话， 则全部注册
	//	如果 rsrc_id 为空， 则将该对象应用到所有资源类型上; 但是此时的资源请求不参与
	//		与制定签名类型的 fetch 的排队， 而单独使用另外的匿名队列， 只有当所有签名
	//		类型的 fetch 都表示无法打开的场合下， 才会使用匿名 fetch 来遍历
	//===========================================================================
	LOLIX_INTERFACE(reg_fetch	, lolix::LOLIX_RETNV
		, (rsrc_fetch* fetch, lolix::LOLIX_ITF_ID const* rsrc_id, size_type* flag_mask));

	//===========================================================================
	//	解除注册一个资源解析插件
	//---------------------------------------------------------------------------
	//	fetch		[i ] =0	: 等待解除注册的 fetch
	//	rsrc_id		[i ] =0	: 从何种资源类型上解除注册
	//	flag_mask	[io] =0	: i: 申请解除注册的类型
	//							  o: 解除注册成功的类型:从低到高分别为 ENUM_CAN_DO
	//								所对应的权限
	//---------------------------------------------------------------------------
	//	fetch 为空的场合， 则把解除注册运用在所有的在该资源类型的注册之上
	//	flag_mask 有效， 则按照指定的标记解除注册， 并且不管返回值如何， 都将会被设置
	//			如果无效， 则全部解除注册
	//	rsrc_id 有效的场合， 按照指定id的资源进行接触， 否则全部指定的句柄上的指定类型
	//			进行运用接触注册
	//	综上所述， 如果希望致空注册序列， 则使用 (0, 0, 0) 参数
	//===========================================================================
	LOLIX_INTERFACE(unreg_fetch	, lolix::LOLIX_RETNV
		, (const rsrc_fetch* fetch, lolix::LOLIX_ITF_ID const* rsrc_id, size_type* flag_mask));

	//===========================================================================
	//	申请一个资源
	//---------------------------------------------------------------------------
	//	src_itf		[ o]	: 返回的资源句柄
	//	uid			[i ]	: 资源ID
	//	flag		[i ]	: 申请标志
	//	rsrc_type	[i ] =0	: 作为id所标记的ID类型打开资源
	//	usr_ptr		[  ]	: 提供给第三方加载插件所使用的一个自定义指针
	//---------------------------------------------------------------------------
	//	rsrc_type 为空的场合， 则使用内部记录的 id 来打开， 如果内部没有合适的记录
	//		则返回失败
	//	可以通过指定 usr_ptr中的 itf_id 来首先出发某一个特定类型的接收器
	//		将会跳过类型不匹配的对象 : 使用 itf_id
	//		如果找不到特定 id, 则返回失败
	//===========================================================================
	LOLIX_INTERFACE(fetch		, lolix::LOLIX_RETNV
		, (rsrc_lacing** src_itf, id_type uid, query_flag flag, lolix::LOLIX_ITF_ID const* rsrc_type, user_data* usr_ptr));

	//===========================================================================
	//	设置资源类型
	//---------------------------------------------------------------------------
	//	uid			[i ]	: 需要查询或者修改的资源
	//	old_id		[ o] =0	: 老的资源类型，=0 表示不需要取得老的ID
	//	new_id		[i ] =0	: 新制定的资源类型, =0 表示不需要设置新的资源ID
	//===========================================================================
	LOLIX_INTERFACE(modi_type	, lolix::LOLIX_RETNV
		, (id_type uid, lolix::LOLIX_ITF_ID* old_id, const lolix::LOLIX_ITF_ID* new_id));

	//===========================================================================
	//	删除一个资源
	//---------------------------------------------------------------------------
	//	uid			[i ]	: 需要被删除的 ID
	//---------------------------------------------------------------------------
	//	已经打开的数据依然有效， 但是存储的时候将会报错
	//===========================================================================
	LOLIX_INTERFACE(erase		, lolix::LOLIX_RETNV
		, (id_type uid));


	//===========================================================================
	//	保存该资源池的内部数据
	//---------------------------------------------------------------------------
	//	rsrc_file	[i ]	: 所固化的文件
	//===========================================================================
	LOLIX_INTERFACE(save_pond	, lolix::LOLIX_RETNV
		, (lolix::loli::file* rsrc_file)const);

	lolix::LOLIX_RETNV	get_type(id_type uid, lolix::LOLIX_ITF_ID* old_id)const
		{ return const_cast<this_type*>(this)->modi_type(uid, old_id, 0); }
	lolix::LOLIX_RETNV	set_type(id_type uid, lolix::LOLIX_ITF_ID const* new_id)
		{ return this->modi_type(uid, 0, new_id); }
	lolix::LOLIX_RETNV	set_type(id_type uid, lolix::LOLIX_ITF_ID const& new_id)
		{ return this->modi_type(uid, 0, &new_id); }
};


class	LOLIX_NO_VTABLE	lxut::rsrc::rsrc_lacing
	: public lolix::itf
{
	LOLIX_DECLARE_ITF(lxut::rsrc::rsrc_lacing, lolix::itf, (0x073025eb, 0xe84c4d19, 0xa3420695, 0x9c699c52));
	typedef	lolix::LOLIX_RETNV		LOLIX_RETNV;
public:
	typedef	rsrc_pond::id_type		id_type;
	typedef	rsrc_pond::user_data	user_data;

	//===========================================================================
	//	得到当前资源的 ID
	//---------------------------------------------------------------------------
	//	# 如果资源被 query 走或者被删除， 则当前返回无效 id
	//===========================================================================
	LOLIX_INTERFACE(id		,	id_type		, (void)const);

	//===========================================================================
	//	删除当前所持有资源
	//---------------------------------------------------------------------------
	//	# 所删除资源如果正在被使用， 则在全部资源被释放之前不会被删除， 但是不可被
	//		query
	//===========================================================================
	LOLIX_INTERFACE(erase	,	void				, (void));

	//===========================================================================
	//	得到当前所持有资源
	//---------------------------------------------------------------------------
	//	out_ptr		[ o]	: 所请求的对象
	//---------------------------------------------------------------------------
	//	LOLIX_ERROR_LESS_RESOURCE : 资源已近被提取， 当前资源无效了
	//---------------------------------------------------------------------------
	//	需要 read 权限
	//	当前资源不能被永久保存， 因为随时可能被修改而导致当前资源过旧
	//===========================================================================
	LOLIX_INTERFACE(get		,	LOLIX_RETNV	, (lolix::itf const** out_ptr)const);
	LOLIX_INTERFACE(get		,	LOLIX_RETNV	, (lolix::itf** out_ptr));


	//===========================================================================
	//	设置当前资源
	//---------------------------------------------------------------------------
	//	src			[i ]	: 设置的资源
	//---------------------------------------------------------------------------
	//	需要写入权限
	//===========================================================================
	//LOLIX_INTERFACE(set		,	LOLIX_RETNV	, (lolix::itf* id));

	//===========================================================================
	//	请求得到当前所持有的资源， 并且脱离资源管理
	//---------------------------------------------------------------------------
	//	out_ptr		[ o]	: 所请求的资源
	//---------------------------------------------------------------------------
	//	LOLIX_ERROR_LESS_RESOURCE : 资源已近被提取， 当前资源无效了
	//	LOLIX_ERROR_LESS_RIGHTS	: 当前资源不允许被提取(比如在共享状态下)
	//===========================================================================
	LOLIX_INTERFACE(query	,	LOLIX_RETNV	, (lolix::itf** out_ptr));


	//===========================================================================
	//	存储当前资源
	//---------------------------------------------------------------------------
	//	dat			[i ] =0	: 所需要存储的地点， 如果为空， 则表示存储到默认介质
	//	usr_data	[i ] =0	: 资源存储时可能需要的自定义控制数据或者其它
	//---------------------------------------------------------------------------
	//	LOLIX_ERROR_UNSUPPORT_FILE_TYPE	: 存储时候， 不支持 file 的实际类型
	//===========================================================================
	LOLIX_INTERFACE(save	,	LOLIX_RETNV	, (lolix::loli::file* dat, user_data* usr_data /* = 0*/)const);
};


class	LOLIX_NO_VTABLE	lxut::rsrc::rsrc_fetch
	: public lolix::itf
{
public:
	LOLIX_DECLARE_ITF(lxut::rsrc::rsrc_fetch, lolix::itf, (0x215091b7, 0x6c934f0a, 0xbb94ec30, 0x3ca44494));

	typedef	__inner::support_flag	support_flag;
	typedef	rsrc_pond::user_data	user_data;
	//===========================================================================
	//	得到对于支持指定资源的支持状况
	//---------------------------------------------------------------------------
	//	spt			[ o]	: 外部已经清 0， 内部不许要多此一举， 标记自己支持的属性即可
	//	id			[i ]	: 对于特定 ID 的支持情况
	//===========================================================================
	LOLIX_INTERFACE(supported	,	void
		, (support_flag* const spt, lolix::LOLIX_ITF_ID const* id)const);

	//===========================================================================
	//	得到当前的顺位状况
	//---------------------------------------------------------------------------
	//	other		[i ]	: 前方的指针， 为空且 *pos(in) 不为0， 表示最后反馈
	//	pos			[io]	:	in : 当前的顺位状况(从1, 或者-1开始计算的)
	//							out: 希望获得的顺位(从1, 或者-1开始计算的)
	//	actie		[i ]	: 如果为真， 则表示自己是插队者
	//---------------------------------------------------------------------------
	//	@	: 如果 actie 为 false, 则返回错误表示反对, 返回成功表示同意插队
	//			如果 actie 为 true, 则返回错误表示放弃插入, 返回成功表示继续谈判
	//---------------------------------------------------------------------------
	//	#	pos : 大于0， 表示顺位，  小于 0 ， 表示逆位, 等于 0, 表示不计较
	//===========================================================================
	LOLIX_INTERFACE(query_regist,	lolix::LOLIX_RETNV
		, (rsrc_fetch* other, lolix::difference_type* pos, bool actie));

	//===========================================================================
	//	存储数据
	//---------------------------------------------------------------------------
	//	src			[i ]	: 需要存储的数据
	//	save_file	[i ]	: 需要存储的介质
	//	rsrc_type	[i ] =0	: 按照此类型存储
	//	usr_data	[  ]	: 外部传入的参数数据
	//---------------------------------------------------------------------------
	//	usr_data->itf_id 只有与自己的 itf_id() 返回相等的时候才会被传入， 并且被激活
	//	rsrc_type 也只有当用户没有指定 rsrc_type 且指定了 usr_data 的 fetch id 才会
	//	为空， 这个状况比较少见， 但是也是合法的， 需要小心决策
	//===========================================================================
	LOLIX_INTERFACE(write		,	lolix::LOLIX_RETNV
		, (lolix::itf const* src, lolix::loli::file* save_file, const lolix::LOLIX_ITF_ID* rsrc_type, user_data* usr_data/* = 0*/));

	//===========================================================================
	//	读取数据
	//---------------------------------------------------------------------------
	//	dec			[ o]	: 读取出来的结果
	//	load_file	[i ]	: 源数据
	//	rsrc_type	[i ] =0	: 按照此类型进行读取
	//	usr_data	[  ]	: 外部传入的参数数据
	//---------------------------------------------------------------------------
	//	usr_data->itf_id 只有与自己的 itf_id() 返回相等的时候才会被传入， 并且被激活
	//	rsrc_type 也只有当用户没有指定 rsrc_type 且指定了 usr_data 的 fetch id 才会
	//	为空， 这个状况比较少见， 但是也是合法的， 需要小心决策
	//===========================================================================
	LOLIX_INTERFACE(read		,	lolix::LOLIX_RETNV
		, (lolix::itf** dec, lolix::loli::file* load_file, const lolix::LOLIX_ITF_ID* rsrc_type, user_data* usr_data/* = 0*/));


	//===========================================================================
	//	新建数据
	//---------------------------------------------------------------------------
	//	new_src		[ o]	: 新建的数据
	//	rsrc_type	[i ] =0	: 按照此类型进行读取
	//	usr_data	[  ]	: 外部传入的参数数据
	//---------------------------------------------------------------------------
	//	返回值说明
	//---------------------------------------------------------------------------
	//	usr_data->itf_id 只有与自己的 itf_id() 返回相等的时候才会被传入， 并且被激活
	//	rsrc_type 也只有当用户没有指定 rsrc_type 且指定了 usr_data 的 fetch id 才会
	//	为空， 这个状况比较少见， 但是也是合法的， 需要小心决策
	//===========================================================================
	LOLIX_INTERFACE(gen			,	lolix::LOLIX_RETNV
		, (lolix::itf** new_src, const lolix::LOLIX_ITF_ID* rsrc_type, user_data* usr_data/* = 0*/));

	template<typename _TSrc> LOLIX_INLINE_CALL lolix::LOLIX_RETNV	write(const _TSrc* src, lolix::loli::file* save_file, user_data* usr_data){return write(src, save_file, &LOLIX_ITF_FROM_TYPE(_TSrc), usr_data);}
	template<typename _TSrc> LOLIX_INLINE_CALL lolix::LOLIX_RETNV	write(const _TSrc* src, lolix::loli::file* save_file){return write(src, save_file, &LOLIX_ITF_FROM_TYPE(_TSrc), 0);}
	template<typename _TSrc> LOLIX_INLINE_CALL lolix::LOLIX_RETNV	read(_TSrc** src, lolix::loli::file* load_file, user_data* usr_data){return read((lolix::itf**)src, load_file, &LOLIX_ITF_FROM_TYPE(_TSrc), usr_data);}
	template<typename _TSrc> LOLIX_INLINE_CALL lolix::LOLIX_RETNV	read(_TSrc** src, lolix::loli::file* load_file){return write((lolix::itf**)src, load_file, &LOLIX_ITF_FROM_TYPE(_TSrc), usr_data, 0);}
	template<typename _TSrc> LOLIX_INLINE_CALL lolix::LOLIX_RETNV	gen(_TSrc** src, user_data* usr_ata){return gen((lolix::itf**)src, &LOLIX_ITF_FROM_TYPE(_TSrc), usr_data);}
	template<typename _TSrc> LOLIX_INLINE_CALL lolix::LOLIX_RETNV	gen(_TSrc** src){return gen((lolix::itf**)src, &LOLIX_ITF_FROM_TYPE(_TSrc), 0);}
};


union	lxut::rsrc::__inner::support_flag
{
	enum { _VER = 2 };
	typedef	lolix::lx_u32	flag_type;
	LOLIX_INLINE_CALL	support_flag(void){}
	LOLIX_INLINE_CALL	support_flag(flag_type t): flag(t){}

	__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING();
	struct
	{
		flag_type	do_gen		: 1;	//	支持新建
		flag_type	do_read		: 1;	//	支持读取
		flag_type	do_write	: 1;	//	支持写入
		flag_type	do_check	: 1;	//	支持校验
		flag_type	do_repair	: 1;	//	支持修复
		flag_type	__res00		: 3;

		flag_type	use_flow	: 1;	//	使用纯流
		flag_type	use_block	: 1;	//	使用块文件
		flag_type	use_bidir	: 1;	//	使用随机
		flag_type	__res01		: 1;
	};

	struct
	{
		flag_type	do_what		: 5;
		flag_type	_res00		: 3;
		flag_type	use_mask	: 3;
		flag_type	_res01		: 1;
	};
	__END_DISABLE_NO_NAME_STRUCT_WARNING();

	flag_type	flag;

	enum	ENUM_CAN_DO
	{	CAN_DO_GEN
	,	CAN_DO_LOAD
	,	CAN_DO_SAVE
	,	CAN_DO_CHECK
	,	CAN_DO_REPAIR
	,	_CAN_DO_CNT
	,	_CAN_DO_VER	= 0
	};

	enum ENUM_USE_MASK
	{	USE_MASK_BLOCK			= 4
	,	USE_MASK_PURE_STREAM	= 3
	,	USE_MASK_STREAM			= 2
	,	_USE_MASK_CNT			= 8
	,	_USE_MASK_VER = 0
	};
};

union	lxut::rsrc::__inner::query_flag
{
	enum { _VER = 3 };
	typedef	lolix::lx_u32	flag_type;
	LOLIX_INLINE_CALL	query_flag(void){}
	LOLIX_INLINE_CALL	query_flag(flag_type t): flag(t){}

	enum	ENUM_OPERATOR
	{	create_new			= 1
	,	create_always		= 2
	,	open_existing		= 3
	,	open_always			= 4
	,	truncate_existing	= 5
	,	_OPERATOR_CNT
	};

	__BEGIN_DISABLE_NO_NAME_STRUCT_WARNING();
	struct
	{
		//	+0x00	bits
		flag_type	operat_read		: 1;	//	读权限: 此标记如果不被指定, 则 query 资源的时候将会 gen 一个新的资源(如果使用 operat_write)
		flag_type	operat_write	: 1;	//	写权限: 一个只读资源 pond 会拒绝写入权限
		flag_type	operat_erase	: 1;	//	删除权限: 一个只读资源 pond 会拒绝删除权限
		flag_type	_rsv_00			: 5;

		//	+0x08	bits
		flag_type	type_mask		: 3;	//	ENUM_OPERATOR
		flag_type	_rsv_01			: 1;

		flag_type	_rsv_02			: 4;

		//	+0x10
		flag_type	from_share		: 1;	//	从共享的资源加载，任何新建相关的指令将导致此标记无效
		flag_type	from_pool		: 1;	//	从共享的数据源加载，任何新建相关的指令将导致此标记无效
		flag_type	from_new		: 1;
		flag_type	_rsv_03			: 1;

		flag_type	submit_share	: 1;	//	资源提交短周期共享
		flag_type	submit_gshare	: 1;	//	资源提交全局共享池
		flag_type	submit_pool		: 1;	//	数据源提交短周期共享
		flag_type	submit_gpool	: 1;	//	数据源提交全局共享池

		//flag_type	share_read		: 1;	//	共享读
		//flag_type	share_write		: 1;	//	共享写
		//flag_type	share_delete	: 1;	//	共享删除
		flag_type	_rsv_04			: 8;
	};
	struct
	{
		flag_type	mask_operat		: 3;
		flag_type	_mask_rsv_00	: 5;

		flag_type	_mask_rsv_01	: 8;

		flag_type	mask_from		: 3;
		flag_type	_mask_rsv_02	: 1;

		flag_type	mask_submit		: 4;
	};
	__END_DISABLE_NO_NAME_STRUCT_WARNING();

	flag_type		flag;
};

//	共享读属性的按照前优先原则， 后续申请刷新缓冲区的要求不会被满足
//	共享写属性按照后优先原则， 后续申请将会覆盖前面的请求
//	申请资源共享某个属性， 必须要求请求时候也请求了此相关属性， 否则对应的共享标记无效

STATIC_ASSERT( sizeof lxut::rsrc::__inner::support_flag == 4 );
STATIC_ASSERT( sizeof lxut::rsrc::__inner::query_flag == 4 );

SYS_REGIST_TYPE(lxut::rsrc::rsrc_fetch);
SYS_REGIST_TYPE(lxut::rsrc::rsrc_lacing);
SYS_REGIST_TYPE(lxut::rsrc::rsrc_pond);
SYS_REGIST_TYPE(lxut::rsrc::rsrc_pond::factory_type);

//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LXUT__RSRC__RSRC_POND__NICK__K_IN_G__)
